const url = require('url')
const Layer = require('./layer')
const Route = require('./route')
const methods = require('methods');

function Router(){
    this.stack = []
}
methods.forEach((method) => {
    Router.prototype.get = function(pathname,handlers){
        const route = new Route()
        const layer = new Layer(pathname,route.dispatch.bind(route)) //创建一个layer
        layer.route = route //标识每一个路由配置一个路由实例
        this.stack.push(layer)
        
        route.get(handlers) 
        // console.log('out',this.stack) 
        // 外层的stack  存的是 路径对应的dispatch方法
        // 里层的stack  存的是 用户的回调
        // 请求匹配的时候，会执行route.dispatch方法，执行里层对应的用户回调
    }
})
Router.prototype.handle = function(req,res,done){
    let {pathname} = url.parse(req.url)
    // 请求带来后迭代外层的stack
    let idx = 0
    const  next = ()=>{ //最精妙的是先执行第一个，将第二个执行逻辑传入到dispatch中，dispatch调用此回调就从第一个走到第二个
        if(idx >= this.stack.length) return done()
        let outLayer = this.stack[idx++]
        if(layer.match(pathname) && layer.route.match_method(req.method.toLowerCase())){
            // 匹配到后调用layer.handler方法，其实就是route.dispatch方法
            outLayer.handler(req,res,next)
        }else{
            // 不匹配则尝试匹配下一个
            next()
        }
    }
    next()  
}
module.exports = Router


// 1） 创建应用会有一个路由系统 （存放的是一层层的）  每一层中存放的 是路径和方法
// 2)  路由系统中的每一层我们都提供一个Route的实例 ， layer.route = new Route
// 3) Route是一个类，每一个路由都有这个实例，实例中会创造一个stack， 用来存放用户注册的回调 （我们把存的回调也封装成layer） 里面的layer不需要在意路径
// 每一个layer需要存放方法 
// 外层的stack 需要匹配路径  ， 里层stack 需要匹配方法